﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace iESELibrary.DESCrypto
{
	/// <summary>
	/// Decryption class implementing MS .Net DES cryptography
	/// </summary>
	public class Decryption : IDisposable
	{
		#region Constants
		private const string KEY_PRODUCT_AQWERTY = @"!@#$%^&*()qwertyUIOPAzxcvbnmQQQQQQQQQQQQ)(*@&%";
		private const string KEY_PRODUCT_ANUM = @"0123456789012345678901234567890123456789";

		private static string PWD_ANT = "NTPASSWORD";
		private static string PWD_ALM = "LMPASSWORD";
		#endregion

		#region Variables
		private bool disposed = false;
		private Vault.SysKey sysKey;
		#endregion

		#region Properties
		public Vault.SysKey SysKey
		{
			get
			{
				return this.sysKey;
			}
		}
		#endregion

		#region Constructors
		/// <summary>
		/// Constructor initiates all keys required to decrypt NTDS.dit file
		/// </summary>
		/// <param name="file">Full absolute SYSTEM file path</param>
		public Decryption(string file)
		{
			this.sysKey = new Vault.SysKey(file);
		}
		#endregion

		#region Public Methods
		/// <summary>
		/// Method decrypts hash (currently only NT) using SysKey
		/// </summary>
		/// <param name="rid">MS AD object RID</param>
		/// <param name="encrypted">Encrypted hash value</param>
		/// <returns></returns>
		public byte[] Decrypt(byte[] encrypted, byte[] key)
		{
			using (DES cryptoDES = DES.Create())
			{
				cryptoDES.Mode = CipherMode.ECB;
				cryptoDES.Padding = PaddingMode.None;
				cryptoDES.IV = new byte[8];

				cryptoDES.Key = key;
				using (ICryptoTransform decryptor = cryptoDES.CreateDecryptor())
				{
					return decryptor.TransformFinalBlock(encrypted, 0, encrypted.Length);
				}
			}
		}
		#endregion

		#region IDisposable Members
		public void Dispose()
		{
			Dispose(true);
			GC.SuppressFinalize(this);
		}

		protected virtual void Dispose(bool disposing)
		{
			if (!this.disposed)
			{
				if (disposing)
				{
					if(this.sysKey != null)
					{
						this.sysKey.Dispose();
					}
				}

				this.disposed = true;
			}
		}
		#endregion
	}
}
